﻿  /*Resource Management Example by Tom Bellingham
    Copyright (C) 2012 Tom Bellingham

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.*/

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;

namespace DictionarySample
{

    //demonstrates handling of loading resources
    //and handling of errors from not found resources or bad input
    public class ResourceManager
    {

        public static ResourceManager Instance;

        Dictionary<string,Texture2D> _textures;
        Dictionary<string, Model> _models;
        Dictionary<string, Song> _music;
        Dictionary<string, Effect> _shaders;
        //etc etc etc for all your meta data types

        ContentManager _content;

        public ResourceManager()
        {

            //exists purely to defeat instantiation
        }

        //returns true if Initialized properly, false if already initialised or error
        //ideally you would have error return types for your engine instead of a bool
        public bool Init(ContentManager content)
        {
            _content = content;

            _textures = new Dictionary<string, Texture2D>();
            _models = new Dictionary<string, Model>();
            _music = new Dictionary<string, Song>();
            _shaders = new Dictionary<string, Effect>();
            return true;

            //hypothetically we could return false if some dependancy or function didn't initialize properly,
            //but we have no need in this simple example;
        }

        public bool LoadTexture(string filename)
        {
            //always check to make sure the string is not null
            if (filename == null)
            {
                throw new Exception("Error: You must provide a filename");
            }//we should catch this, but we won't for now

            try
            {
                _textures.Add(filename, _content.Load<Texture2D>(filename));
            }
            catch (ContentLoadException e)
            {
                
                //once again, if our engine implements error codes and things like that, we can use them to communicate
                //the information in 'e' directly back to the programmer, so they can continue to debug, or fix the error, 
                //making it THEIR choice whether to ignore or fix the issue
                

                //for our purposes we will just return false
                return false;
            }
            return true;
        }
        //now we would have other functions that load models, sounds, videos, shaders, and anything else the same way we loaded the texture




        public Texture2D GetTexture(string assetName)
        {
            //always check to make sure the string is not null
            if (assetName == null)
            {
                throw new Exception("Error: You must provide an assetname");
            }

            if (_textures.ContainsKey(assetName))
            {
                return _textures[assetName];
            }
            else
            {
                throw new Exception("Error: Asset with name \'" + assetName + "\' not loaded");
            }
        }
        //now we hypothetically would want to return an 'asset doesn't exist' error
        //but that is beyond the scope of this, here we will throw and exception



        public void UnloadTexture(string assetName)
        {
            //always check to make sure the string is not null
            if (assetName == null)
            {
                throw new Exception("Error: You must provide an assetname");
            }

            if (_textures.ContainsKey(assetName))
            {
                _textures.Remove(assetName);
            }
        }
        //this provides a way to dispose of unused assets




        //this function doesn't do anything right now.
        //you would use it to load a lot of assets at once, from a text file
        //using a format of your own design
        //the benefits of this is that you can load the assets and change the manifest
        //without recompiling your code every single time an asset is added to a level
        //the formatting and parsing of such a file is up to you
        public void LoadManifest(string manifestFilename)
        {
            //always check to make sure the string is not null
            if (manifestFilename == null)
            {
                throw new Exception("Error: You must provide an manifestFilename");
            }

            //now we would check to see the manifest file exists
            //using File.Exists from System.IO

            //once the file is loaded you would scroll through each filename, and load it using
            //the right function so if its a texture you call the function we made above
        }

    }
}
